import type from 'component-type'
import uiUtil from '../ui-components/util'

const toString = Object.prototype.toString

export default {

  // 粗略计算，不包含标点
  strLen(str) {
    return str.split('').reduce((prev, cur, index) => {
      return prev + (/^[a-zA-Z]$/.test(cur) ? 0.5 : 1);
    }, 0);
  },

  // 粗略计算，不包含标点
  strSlice(str, _from, _to) {
    str = str.slice(_from);
    let ret = '';
    let i = 0;
    while(Math.floor(this.strLen(ret)) !== _to && i < str.length) {
      ret += str[i++];
    }
    return ret;
  },

  getImagePath() {
    return process.env.NODE_ENV === 'production'? './static/images': './static/src/images'
  },

  user(user) {
    if (this.isNull(user)) {
      return {
        fullName: '已删除',
        avatarUrl: '',
        jobTitle: '',
        jobTitleName: ''
      }
    }
    return user
  },

  size(_byte) {
    if (_byte == null ) return ''
    const items = ['B', 'K',  'M']
    let deep = 0
    while(_byte > 1024) {
      _byte = _byte/1024
      deep += 1
    }
    _byte = Math.ceil(_byte)
    return `${_byte}${items[deep]}`
  },

  time(timestamp, spllitter) {
    if (this.isNull(timestamp)) return ''
    const d = new Date(+timestamp)
    return [
      d.getFullYear(), 
      d.getMonth()+1, 
      d.getDate()
    ].join(spllitter || '.')
  },
  dateFormat: function (time, fmt) { //author: meizz 
      var o = {
          "M+": time.getMonth() + 1, //月份 
          "d+": time.getDate(), //日 
          "h+": time.getHours(), //小时 
          "m+": time.getMinutes(), //分 
          "s+": time.getSeconds(), //秒 
          "q+": Math.floor((time.getMonth() + 3) / 3), //季度 
          "S": time.getMilliseconds() //毫秒 
      };
      if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (time.getFullYear() + "").substr(4 - RegExp.$1.length));
      for (var k in o)
      if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
      return fmt;
  },
  formatFloat (f, digit=1) { 
    const m = Math.pow(10, digit); 
    return Math.ceil(parseInt(f * m, 10) / m); 
  },

  // 接收一个url 一个元素的宽度
  // 如果有切割参数，返回对应的样式
  crop(url, width) {
    let [ _, info ] = decodeURIComponent(url).split('|')
    if (info) {
      let eSite =info.search(/[a-z|A-Z]/i);
      if(eSite > -1) {
          info = info.substring(0, eSite-1);
      }
      let [x, y, e] = info.split(',')
      return {
        backgroundPosition: `${x}% ${y}%`,
        backgroundSize: `${width/(e/100)}px auto`,
        backgroundRepeat: 'no-repeat',
      }
    } else {
      return {
        backgroundSize: 'cover',
        backgroundPosition: '50% 50%',
        backgroundRepeat: 'no-repeat',
      }
    }
  },

  throttle: uiUtil.throttle,

	// safe
	find(arr=[], cb) {
		return arr.filter(cb)[0] || {}
	},

	copy(source, target) {
		for(let i in target) {
			if (target.hasOwnProperty(i)) {
				if (source[i] !== undefined) {
					target = {
						...target,
						[i]: source[i]
					}
				}
			}
		}
		return target
	},

  space(n) {
    let i=0
    let str=''
    while(i++<n)
      str += String.fromCharCode(160)
    return str
  },

  isEqual(a, b) {
		if (!a) a = ''
		if (!b) b = ''
		a = '' + a
		b = '' + b
    return a.toLowerCase() == b.toLowerCase()
  },

  isString(a) {
    return typeof a === 'string'
  },

	deepClone(obj) {
		if (this.isObject(obj)) {
			var _obj = {}
			for(var i in obj) {
				if (obj.hasOwnProperty(i)) {
					_obj[i] = this.deepClone(obj[i])
				}
			}
			return _obj
		}

		if (Array.isArray(obj)) {
			var arr = []
			for(var i=0;i<obj.length;i++) {
				arr[i] = this.deepClone(obj[i])
			}
			return arr
		}

		return obj
	},

  // toggle dialog
  dialog(name) {
    this.setState({
      [name]: 1 - this.state[name]
    })
  },

  type(obj) {
    return type(obj)
  },

  isShallowEqual(a, b) {
		const type = this.type(a)
		// 值相等
		if (a == b) return true

		if(type !== this.type(b)) {
			return false
		}

		if (type === 'string') {
			if (a.toLowerCase() === b.toLowerCase()) return true
		}

		if (type === 'array') {
			if (a.length !== b.length) {
				return false
			}
			return a.every((item,i) => this.isShallowEqual(item, b[i]))
		}

		if (type === 'object') {
			const keys = Object.keys(a)
      if (keys.length !== Object.keys(b).length) {
        return false
      }

      if (keys.some(key => !~Object.keys(b).indexOf(key))) {
        return false
      }

			return keys.every(key => this.isShallowEqual(a[key], b[key]))
		}
  },

  isObject(obj) {
    return this.type(obj) === 'object'
  },

  last(arr) {
    const length = arr.length
    return arr[length-1] || null
  },

  isObjectEmpty(obj) {
    for(let i in obj) {
      if (obj.hasOwnProperty(i)) return false
    }
    return true
  },

  isString(obj) {
    return typeof obj === 'string'
  },

	isNull(obj) {
		if (obj == null || !obj) return true
    if (Array.isArray(obj)) return !obj.length
    if (this.isString(obj)) return !obj.trim().length
    if (this.isObject(obj)) return this.isObjectEmpty(obj)
	},

	filter(obj, fn) {
		if (Array.isArray(obj)) {
			return obj.filter(fn)
		}
		let _obj = {}
		for(var i in obj) {
			if (obj.hasOwnProperty(i)) {
				if (fn(obj[i], i)) _obj[i] = obj[i]
			}
		}
		return _obj
	},

  link(arr) {
    let obj = {}
    const context = this
    for(let i in context) {
      obj[i] = context[i].bind(arr)
    }
    return obj
  },

	emoji: {
	  enc(str) {
			const high = /[\uD800-\uDBFF]/
			const low = /[\uDC00-\uDFFF]/ 
			let match1
			let match2
			let word
			if ((match1 = str.match(high))) {
				if ((match2 = str.match(low))) {
					word = match1 + match2
					return str.replace(word, encodeURIComponent(word)) 
				}
			}
			return str
		},
		dec(str) {
      try{
        return str.replace(/((%[A-Z0-9]{2}){4})/g, function(v){return decodeURIComponent(v)}) //decodeURIComponent(str);
      }catch(e) {
        return str;
      }
		}
	},

	serialize(obj) {
		const keys = Object.keys(obj).sort()
		let arr = []
		keys.forEach(key => {
			arr.push(encodeURIComponent(`${key}=${obj[key]}`))
		})
		return arr.join('&')
	},

  body(obj={}) {
    const keys = Object.keys(obj)
      .filter(key => obj[key] != null)

    if (!keys.length) return ''

    const arr = []

		keys.forEach(key => {
			arr.push(`${key}=${encodeURIComponent(obj[key])}`)
		})

    return arr.join('&')
  },

	parse(str) {
		const arr = str.split('&')
		let map = {}
		for(let i in arr) {
			const [ key, value ] = arr[i].split('=')
			map[key] = value
		}
		return map
	},

  link(arr) { 
    const context = this 
    let obj = {} 
    for(let i in context) {
      obj[i] = context[i].bind(obj, arr)
    }
    return obj
  },

  substr(str, length) {
    if (str.length > length-3) {
      return str.substring(0, length) + '...'
    } else {
      return str
    }
  },
  preventDefaultEvent(e) {
    e.preventDefault();
  },
  
}
